﻿/*
 * Creato da SharpDevelop.
 * Utente: Ciccio
 * Data: 13/07/2008
 * Ora: 11.11
 * 
 * To change this template use Tools | Options | Coding | Edit Standard Headers.
 */

using System.Data;
using System.Web;
using System;
using ACM.cmsarea08.Administration;

namespace ACM.cmsarea08.Administration.Core
{
	/// <summary>
	/// Description of Class1.
	/// </summary>
	public class AdminMenuGenerator2
	{
		private static AdminMenuGenerator2 _istanza=null;
		private static object locker = new object();
		private ACM.cmsarea08.Administration.Core.DBClass dclass;
		private const string common_folder = "/administration/template/admimg/";
		private DataSet _myadminMenu = null;
		public static AdminMenuGenerator2 adminMenu {
			get {
				if(_istanza==null) {
					lock(locker) { _istanza = new AdminMenuGenerator2(); }
				}
				return _istanza;
			}
		}
		
		public DataSet AdminMenu {
			get {
				if(HttpContext.Current.Session==null) {
					return _myadminMenu;
				}
				object mymenu = HttpContext.Current.Session["myAdminMenu"];
				if(mymenu == null) return null;
				if(mymenu is DataSet) return (DataSet)mymenu;
				return null;
			}
			set {
				if(HttpContext.Current.Session!=null) 
					HttpContext.Current.Session["myAdminMenu"] = value;
				else
					_myadminMenu = value;
			}
		}
		
	
		
		#region costanti_query
			const string bMenu_lingua = "select distinct * from {0}admin_menu " +
			                          "where enabled='1' and (lingua='{1}' or lingua='') order by figliodi,ordine ;";
			const string bMenu_linguaruoli = "select distinct * from {0}admin_menu " +
			                          "where enabled='1' and (lingua='{1}' or lingua='') and ({2}) order by figliodi,ordine ;";
			const string bUserRules = "select distinct " +
				"cast(uroles.role as char) as `role`," +
				"cast(uroles.relatedto as char) as `relatedto`, " +
				"cast(uroles.admin_menu as char) as `admin_menu`," +
				"cast(uroles.position  as char) as `position`," +
				"cast(uroles.id as char) as `id`, " +
				"cast(uroles.order  as char) as `order`," +
				"cast(uroles.sonof as char) as `sonof`," +
				"cast(uroles.operation  as char) as `operation`," +
				"cast(uroles.nomevoce  as char) as `nomevoce`," +
				"cast(uroles.lang as char) as `lang`, " +
				" cast(if(avoice.link is null,'#',avoice.link) as char)  as av_link ," +
				" cast(if(avoice.ruolo is null,uroles.relatedto,avoice.ruolo) as char)  as av_ruolo," +
				" cast(if(avoice.enabled is null, '1',avoice.enabled) as char)  as av_enabled," +
				" cast(if(avoice.figliodi is null,uroles.sonof,avoice.figliodi) as char)  as av_figliodi, " +
				" cast(if(avoice.ordine is null, uroles.order,avoice.ordine) as char)  as av_ordine, " +
				" cast(if(avoice.target is null,'_self',avoice.target) as char)  as av_target," +
				" cast(if(avoice.lingua is null,uroles.lang, avoice.lingua) as char)  as av_lingua ," +
				" cast(if(avoice.id_component is null,'-1',avoice.id_component) as char)  as av_id_component , " +				
				" cast(if(avoice.nome is null,uroles.nomevoce,avoice.nome) as char)  as av_nome , " +
				" cast(if(avoice.urlimg is null,'',avoice.urlimg) as char)  as av_urlimg, " +
				" cast(if(avoice.id_instance is null,'-1',avoice.id_instance) as char)  as av_id_instance," +
				" cast(if(avoice.name_group is null,'',avoice.name_group) as char)  as av_name_group, " +
				" cast(if(avoice.link is null,'1','0') as char) as customME " +
                " from {0}user_menu as uroles " +
				" left join {0}admin_menu as avoice on uroles.admin_menu = avoice.id and uroles.lang=avoice.lingua and avoice.enabled='1' " +
                " where uroles.relatedto='{1}' and uroles.position='top' and uroles.role='group' and (uroles.lang='{2}' or uroles.lang='') " +
				" order by uroles.sonof  ";
			
		
				
		#endregion
		
		
		
		public AdminMenuGenerator2()
		{
			dclass= new Administration.Core.DBClass();
		}
		public string getMainMenu(string role, string score, string[] dep, string security,string language,MenuModes mode,string htmlID) {
			string getMenu = this.processMenu(role,score,dep,security,language,true,false);
			if(string.IsNullOrEmpty(getMenu)) return string.Empty;
			if(mode==MenuModes.Plain) return getMenu;
			//prepara lo scorsoio per gli elementi:
			string xslPath = mode.ToString().ToLower()+".xsl";
			getMenu=getMenu.Replace("<root>","<root><htmlid>"+htmlID+"</htmlid>");
			getMenu = getMenu.Replace(@"\n","").Replace(@"\r","").Replace(@"\\","").Replace("\n","").Replace("\r","").Replace("  "," ").Trim();
			if(!System.IO.File.Exists(AppDomain.CurrentDomain.BaseDirectory + "\\administration\\template\\xsl\\"+xslPath)) return getMenu;
			string errori = "";
			string dato = ACM.cmsarea08.Function.TextClass.textclass.getXmlTransformationString(getMenu,
			                                                                                    AppDomain.CurrentDomain.BaseDirectory + "\\administration\\template\\xsl\\"+xslPath,
			                                                                                    out errori);
			if(!string.IsNullOrEmpty(errori)) {
				dato+=errori;
			}
			return dato;
		}

	
		public enum MenuModes {
			List,
			Accordion,
			Plain
		}
		
		
#region RigheperilMenu
		
		
		const string xmlNodo = ""+
				"<item>"+
				"	<name>{0}</name>"+
				"	<link>{1}</link>"+
				"	<img>{2}</img>"+
				"	<class>{3}</class>"+
				"	<suffixurl>{4}</suffixurl>"+
				"	<role>{5}</role>"+
				"	<idmod>{6}</idmod>"+			
				"	<idcomp>{7}</idcomp>"+									
				"	<componentpath>{8}</componentpath>"+
				"	<unique>{9}</unique>"+		
				"	{10}"+
				"</item>";

		public string processMenu ( string role, string score, string[] dep, string security,string lingua) {
			return processMenu(role,score,dep,security,lingua,true);
		}
		public string processMenu ( string role, string score, string[] dep, string security,string lingua,bool applyCustom) {
			return processMenu(role,score,dep,security,lingua,applyCustom,false);
		}		
		
		public string processMenu ( string role, string score, string[] dep, string security,string lingua,bool applyCustom,bool forcecustom) {
				DataSet roleMenu = null;
				DataSet moduleList = null;
				string xmlMenu = string.Empty;
				
			
				if(score.Trim().Length==0) {
					score = "10000";
				}
				if(score.Trim()=="0") score = "0";
				
				//carica il menu del livello richiesto (e con il valore corretto)
				string whereSecurity = makeSecurityFilter(security);
				string queryMenu = string.Format(
										  "select distinct *  " +
										  "from {0}admin_menu " +
				                          "where {3} role_score>={2} and enabled='1' and category<>'PP' " +
				                          "and (lingua='{1}' or lingua='') order by figliodi asc,ordine asc;",
				                          dclass.TablePrefix,lingua,score,whereSecurity);
				roleMenu = dclass.ExecuteDataset(queryMenu);
				
				
				
				//alla query dei moduli applico comunque un filtro sui moduli disponibili?
				// " where md.id not in (select menu_id from {0}usermenu as umm where umm.rolename='{1}' and operation='R')" 
				
				string queryMods = string.Format(
										  " select distinct md.titolo,md.id,md.id_componente, cpp.url_path as componentpath " +
										  " from {0}moduli as md left join {0}componenti as cpp on md.id_componente = cpp.id " +
										  " order by titolo ;",
				                          dclass.TablePrefix,role);
				moduleList = dclass.ExecuteDataset(queryMods);
				
				
				
				

				if(roleMenu==null)
					return queryMenu;
				
				//crea base Menu: 
				xmlMenu = this.getChildMenu("-1",roleMenu.Tables[0]);
				//se base_menu esiste è contiene voci
				if(xmlMenu.Length>0) xmlMenu = "<items>"+ xmlMenu +"</items>";
				//prepara il plugins menu.
				string childMenu = "";
				if(moduleList!=null) {
					//predisponi lettura dell'elenco dei moduli e preoccupati della generazione delle voci di menu.
					for(int x = 0 ; x<moduleList.Tables[0].Rows.Count; x++ ) {
						//verifica se il file esiste.	
						DataRow dr = moduleList.Tables[0].Rows[x];
						string file = "/controls/" + dr["componentpath"] +"/form/menu_" + lingua + ".xml";
						if(!System.IO.File.Exists(HttpContext.Current.Server.MapPath(file)) )
							file = "/controls/" + dr["componentpath"] +"/form/menu.xml";
						if(!System.IO.File.Exists(HttpContext.Current.Server.MapPath(file)) ) //in questo caso significa che non esiste il file menu. quindi sorvola.
							continue;
						//ok posso leggere il file.
						System.Xml.XmlDocument xdoc = new System.Xml.XmlDocument();
						try {
						xdoc.Load(HttpContext.Current.Server.MapPath(file));
						} catch {
							HttpContext.Current.Response.Write("Warning - Module : " + dr["componentpath"] + ", non caricato");
							continue;
						}
						System.Xml.XmlNode xroot = xdoc.SelectSingleNode("//menu");
						System.Xml.XmlNode x_link = xdoc.SelectSingleNode("//menu/link");
						System.Xml.XmlNode x_img = xdoc.SelectSingleNode("//menu/img");
						System.Xml.XmlNode x_name = xdoc.SelectSingleNode("//menu/name");
						System.Xml.XmlNode x_surl = xdoc.SelectSingleNode("//menu/suffixurl");
						System.Xml.XmlNode x_class = xdoc.SelectSingleNode("//menu/class");
						System.Xml.XmlNode x_role = xdoc.SelectSingleNode("//menu/role");
						System.Xml.XmlElement x_root = xdoc.CreateElement("item");
						if(x_name == null) {
							x_name = xdoc.CreateElement("name");
							x_name.InnerText = dr["titolo"].ToString();
						} 
						if(x_link == null) {
							x_link = xdoc.CreateElement("link");
							x_link.InnerText = "#";
						}
						if(x_img == null) {
							x_img = xdoc.CreateElement("img");
							x_img.InnerText = "";
						}
						if(x_class == null) {
							x_class = xdoc.CreateElement("class");
							x_class.InnerText = "";
						}
						if(x_surl == null) {
							x_surl = xdoc.CreateElement("suffixurl");
							x_surl.InnerText = "";
						}
						if(x_role == null) {
							x_role = xdoc.CreateElement("role");
							x_role.InnerText = "1000";
						}
						
						System.Xml.XmlElement x_id = xdoc.CreateElement("idmod");
						x_id.InnerText = dr["id"].ToString();
						System.Xml.XmlElement x_comp= xdoc.CreateElement("idcomp");
						x_comp.InnerText = dr["id_componente"].ToString();
						System.Xml.XmlElement x_path= xdoc.CreateElement("componentpath");
						x_path.InnerText = dr["componentpath"].ToString();
						System.Xml.XmlElement x_unique= xdoc.CreateElement("unique");
						x_unique.InnerText = "MD_" + dr["id"].ToString();
						System.Xml.XmlElement x_container= xdoc.CreateElement("items");
	
						x_root.AppendChild(x_name);
						x_root.AppendChild(x_link);
						x_root.AppendChild(x_img);
						x_root.AppendChild(x_class);
						x_root.AppendChild(x_surl);
						x_root.AppendChild(x_role);
						x_root.AppendChild(x_id);
						x_root.AppendChild(x_comp);
						x_root.AppendChild(x_path);
						x_root.AppendChild(x_unique);
						x_root.AppendChild(x_container);
						
						System.Xml.XmlNodeList xfili = xdoc.SelectNodes("//menu/items/item");
						for(int i = 0 ; i<xfili.Count; i++) {
							System.Xml.XmlNode xuni = x_unique.CloneNode(true);
							xuni.InnerText= x_unique.InnerText + "_" + i;
							System.Xml.XmlNode xlik = xfili[i].SelectSingleNode("link");
							if(xlik!=null)  {
								string curLink =xlik.InnerText;
								if(!curLink.StartsWith("/") && !curLink.StartsWith("http://"))
									curLink = "/controls/" + x_path.InnerText + "/" + curLink;
								xlik.InnerText = curLink;
							}
							xfili[i].AppendChild(x_id);
							xfili[i].AppendChild(x_comp);
							xfili[i].AppendChild(xuni);
							x_container.AppendChild(xfili[i].CloneNode(true));
						}
						childMenu+=x_root.OuterXml;
					}
				}
				//ora che ho riempito tutti i container posso creare l'xml document del menu...
				System.Xml.XmlDocument xdochi = new System.Xml.XmlDocument();
				try {
					xdochi.LoadXml(xmlMenu);
				} catch (Exception ex) {
					HttpContext.Current.Response.Write("Warning - Impossibile Caricare Menu: " + xmlMenu + ", " + ex);
					return string.Empty ;
				}
				
				
				//se posso avere childPlugins carico la funzione ...
				if(childMenu.Length>0) {
					//xmlMenu+=childMenu;
					System.Xml.XmlNode xplugins = xdochi.SelectSingleNode("//items/item[unique='STD45']");
					if(xplugins!=null) {
						System.Xml.XmlNode xIte = xdochi.CreateElement("items");
						xIte.InnerXml =(childMenu);
						xplugins.AppendChild(xIte);
					}
				}
				
				//adesso tutto è pronto per essere scremato in funzione di customizzazioni varie.
				string queryCustom = string.Format(
										  " select * " +
										  " from {0}usermenu where rolename='{1}' " +
										  " order by parent_xpath asc ;",
				                          dclass.TablePrefix,role);
				DataSet ds = null; 
				if(applyCustom==true) ds = dclass.ExecuteDataset(queryCustom);
				if(ds==null) applyCustom=false;
				//leggere le regole e applicare il visible not visible a tutte le voci...
				if(applyCustom==true || forcecustom==true) {
					//qui applico.
					//se non ho result dal DB: azzero tranne voce Pann. e Aiuto.
					System.Xml.XmlNode _start = xdochi.SelectSingleNode("//items/item[unique='STD1']");
					System.Xml.XmlNode _end = xdochi.SelectSingleNode("//items/item[unique='STD21']");
					System.Xml.XmlNode _startLock = xdochi.CreateElement("locked");
					_startLock.InnerText="true";
					_start.AppendChild(_startLock);
					System.Xml.XmlNode _endLock = xdochi.CreateElement("locked");
					_endLock.InnerText="true";
					_end.AppendChild(_endLock);
					string xmlMenuFinale = xdochi.OuterXml;		
					System.Xml.XmlNodeList valu = xdochi.SelectNodes("//items/item");
					for(int i = 0 ;i<valu.Count; i++) {
						if(valu[i]!=_start && valu[i]!=_end) {
							valu[i].ParentNode.RemoveChild(valu[i]);
						}
					}						
					//sposta un child:
					//xdochi.AppendChild(_end);					
					if(ds!=null) {
						xdochi=ParseMenu(xdochi,xmlMenuFinale,ds,_end);
					}
				}
				//...				
				//dopo l'applicazione dei permessi e delle funzioni riporto tutto su xmlMenu
				xmlMenu = xdochi.OuterXml;
				if(xmlMenu.Length>0) 
					xmlMenu = "<root>" + xmlMenu + "</root>";
				return xmlMenu;
		}
		private System.Xml.XmlDocument ParseMenu(System.Xml.XmlDocument current,string menu, DataSet custom,System.Xml.XmlNode _posizione) {
			bool append = false;
			if(_posizione==null) append = true;
			System.Xml.XmlDocument completeMenu = new System.Xml.XmlDocument();
			try {
			completeMenu.LoadXml(menu);
			} catch( Exception ex) {
				//HttpContext.Current.Response.Write("ERRORE PARSING: " + ex + "\n\n" + menu);
				return current;
			}
//			HttpContext.Current.Response.Write("SONO QUI\n\n" +menu);
			//insertPoint: 
			System.Collections.Generic.List<System.Xml.XmlNode> nodi = 
				new System.Collections.Generic.List<System.Xml.XmlNode>();
			DataRow[] drs = custom.Tables[0].Select("parent_xpath='//root/items'");
			int column = custom.Tables[0].Columns.Count;
			for(int i = 0;i<drs.Length;i++) {
				DataRow dr = drs[i];
				string menuID = "";
				string parent = "";
				string oParent="";
				string xmlData = "";
				for(int c=0;c<column;c++) {
					object o = dr[c];
					if(o is byte[]) o = System.Text.Encoding.UTF8.GetString((byte[])o);
					else o = o.ToString();
					o = HttpUtility.HtmlDecode(o.ToString());
					switch (custom.Tables[0].Columns[c].ColumnName.ToLower()) {
						case "menu_id" :
							menuID = o.ToString();
							break;
						case "parent_xpath" :
							parent = o.ToString();
							break;	
						case "original_xpath" :
							oParent = o.ToString();
							break;				
						case "dataxml" :
							xmlData = o.ToString();
							break;								
					}
				}
				//trova la posizione: 
				if(parent.StartsWith("//root/") ) parent = "//" + parent.Substring(7);
				System.Xml.XmlNode nodoParente = null; 
				if(append==true) 
					nodoParente = current.SelectSingleNode(parent);
				else 
					nodoParente = _posizione.ParentNode;
				
				if(nodoParente==null) continue;
				try {
					if((!string.IsNullOrEmpty(oParent)) && string.IsNullOrEmpty(xmlData) ) {
						if(oParent.StartsWith("//root/") ) oParent = "//" + oParent.Substring(7);
						System.Xml.XmlNode _node = completeMenu.SelectSingleNode(oParent);
						if(_node!=null) {
							System.Xml.XmlElement x_root = current.CreateElement("item");
							
							x_root.InnerXml = _node.InnerXml;
							if(!string.IsNullOrEmpty(oParent)) {
								System.Xml.XmlElement x_xpath = current.CreateElement("xpath");
								x_xpath.InnerXml = oParent;
								x_root.AppendChild(x_xpath);
							}
							string figli = getSons("//root" + parent.Substring(1) + "/item[unique=''"+menuID+"'']",custom.Tables[0],completeMenu,"");
							if(figli.Trim().Length>0) {
								System.Xml.XmlElement x_sons = current.CreateElement("items");
								x_sons.InnerXml = figli;
								x_root.AppendChild(x_sons);
							}
							if(append==true)
								nodoParente.AppendChild(x_root);
							else
								nodoParente.InsertBefore(x_root,_posizione);
						}				
					} else {
						//...crea nodo..
						System.Xml.XmlElement x_root = current.CreateElement("item");
						if(xmlData.Substring(0,6).ToLower()=="<item>") 
							xmlData = xmlData.Substring(6);
						if(xmlData.Substring(xmlData.Length-7).ToLower()=="</item>")
							xmlData =xmlData.Substring(0,xmlData.Length-7);
						x_root.InnerXml = xmlData;
						
						if(!string.IsNullOrEmpty(oParent)) {
							System.Xml.XmlElement x_xpath = current.CreateElement("xpath");
							x_xpath.InnerXml = oParent;
							x_root.AppendChild(x_xpath);
						}			
						
						string figli = getSons("//root" + parent.Substring(1)+ "/item[unique=''"+menuID+"'']",custom.Tables[0],completeMenu,"");
						if(figli.Trim().Length>0) {
							System.Xml.XmlElement x_sons = current.CreateElement("items");
							x_sons.InnerXml = figli;
							x_root.AppendChild(x_sons);
						}
						if(append==true)
							nodoParente.AppendChild(x_root);
						else
							nodoParente.InsertBefore(x_root,_posizione);
							
					}
				} catch(Exception ex) {
					//HttpContext.Current.Response.Write("SONO ERROE IN CREAZIONE: " +ex + "\n\n"+ oParent + " -_>" + xmlData+"\n\n\n\n");
					continue;
				}
			
			}
			return current;
		}
		private string getSons(string currentPath,DataTable dt,System.Xml.XmlDocument master,string pre) {
//			HttpContext.Current.Response.Write("\n\nTEST: " + currentPath);
			DataRow[] drs = new DataRow[0];
			try {
				drs = dt.Select("parent_xpath='"+currentPath+"'");
			} catch(Exception ex) {
//				HttpContext.Current.Response.Write("\n\nEETEST: " + ex);
				return string.Empty;
			}
//			HttpContext.Current.Response.Write(", Figli: " + drs.Length);
			int column = dt.Columns.Count;
			string sons=pre;
			for(int i = 0;i<drs.Length;i++) {
				DataRow dr = drs[i];
				string menuID = "";
				string parent = "";
				string oParent="";
				string xmlData = "";
				for(int c=0;c<column;c++) {
					object o = dr[c];
					if(o is byte[]) o = System.Text.Encoding.UTF8.GetString((byte[])o);
					else o = o.ToString();
					o = HttpUtility.HtmlDecode(o.ToString());
					switch (dt.Columns[c].ColumnName.ToLower()) {
						case "menu_id" :
							menuID = o.ToString();
							break;
						case "parent_xpath" :
							parent = o.ToString();
							break;	
						case "original_xpath" :
							oParent = o.ToString();
							break;				
						case "dataxml" :
							xmlData = o.ToString();
							break;								
					}
				}
				//trova la posizione: 
				string figlio = "";
				if((!string.IsNullOrEmpty(oParent)) && string.IsNullOrEmpty(xmlData) ) {
//					HttpContext.Current.Response.Write("\nPOTENZIALE FLIGO:" + oParent);
					if(oParent.StartsWith("//root/") ) oParent = "//" + oParent.Substring(7);
					System.Xml.XmlNode _node = master.SelectSingleNode(oParent);
					if(_node!=null) {
						figlio= _node.InnerXml;
						if(!string.IsNullOrEmpty(oParent)) {
							figlio=figlio.Replace("</item>","") + "<xpath>" + oParent + "</xpath>";
						}							
					} 
//					else{
//						HttpContext.Current.Response.Write("\nin potenza null:" + oParent);
//					}
				} else {
					if(xmlData.Substring(0,6).ToLower()=="<item>") 
						xmlData = xmlData.Substring(6);
					if(xmlData.Substring(xmlData.Length-7).ToLower()=="</item>")
						xmlData =xmlData.Substring(0,xmlData.Length-7);
					figlio = xmlData;
					if(!string.IsNullOrEmpty(oParent)) {
						figlio=figlio.Replace("</item>","") + "<xpath>" + oParent + "</xpath>";
					}							
				}
				//check for sons...
				figlio = "<item>"+figlio;
//				HttpContext.Current.Response.Write("\n\tTROVATO FLIGO:" + figlio);
				string figli =getSons(parent.Replace("'","''")+"/item[unique=''"+menuID+"'']",dt,master,"");
				if(figli.Trim().Length>0) {
					figlio=figlio+"<items>" + figli + "</items></item>";
				} else
					figlio =figlio+"</item>";
				sons+=figlio;
			}
			return sons;
		}
		private string getChildMenu(string padre, DataTable dt ) {
				DataRow[] dd = dt.Select("figliodi ='"+padre+"'"); 
				string bbMenu = "";
				for(int x = 0 ; x<dd.Length; x++ ) {
					DataRow dr = dd[x];
					string trysons = this.getChildMenu(dr["id"].ToString(),dt);
					string urloImg = dr["urlimg"].ToString().ToLower();
					if(urloImg.Trim().Length>0) {
						if(urloImg.IndexOf("\n")!=-1) urloImg = urloImg.Replace("\n","");
						if(urloImg.IndexOf("\r")!=-1) urloImg = urloImg.Replace("\r","");
						urloImg = urloImg.Replace(" ","");
						
						if(urloImg.StartsWith("..") || urloImg.StartsWith("/") || urloImg.StartsWith("http://")) {
							//buono:
							urloImg = urloImg.Trim();
						} else
							urloImg = string.Empty;
						
						
					} else urloImg = string.Empty;
					bbMenu+= string.Format(xmlNodo, 
					                       dr["nome"].ToString(),
					                       HttpUtility.HtmlEncode(dr["link"].ToString()),
					                       urloImg,
					                       "cssclass",
					                       "suffixurl",
					                       dr["role_score"].ToString(),
					                       dr["id_instance"].ToString(),
					                       dr["id_component"].ToString(),
					                       "comppath",
					                       "STD" + dr["id"].ToString(),
					                       trysons.Length>0?("<items>" + trysons + "</items>"):"");
				}
			return bbMenu;
		}
		const string baseSecurity = "000000000000000000000000000001";
		private string makeSecurityFilter(string security) {
				//controllo di sistema per prevenire crash sulla security
				if(string.IsNullOrEmpty(security))
					return baseSecurity;
				if(security.Length<30) 
					return baseSecurity;
				
				string wherefilt = "";
				//contenuti:
				if ( security.Substring(1,12).IndexOf('1')==-1) {
					wherefilt += " left(category,1)<>'C' and";	
				} else {
					if(security.Substring(1,4).IndexOf('1')==-1)
						wherefilt += " category<>'CS' and";
					if(security.Substring(4,4).IndexOf('1')==-1)
						wherefilt += " category<>'CC' and";
					if(security.Substring(8,4).IndexOf('1')==-1)
						wherefilt += " category<>'CA' and";
				}
				//template:
				if(security.Substring(13,3).IndexOf('1')==-1)
					wherefilt += " category<>'ST' and";
				//statistiche:
				if(security.Substring(17,1).IndexOf('1')==-1)
					wherefilt += " category<>'SS' and";
				//utenti:
				if ( security.Substring(17,8).IndexOf('1')==-1) {
					wherefilt += " left(category,1)<>'U' and";	
				} else {
					if(security.Substring(17,1).IndexOf('1')==-1)
						wherefilt += " category<>'UU' and";
					if(security.Substring(18,1).IndexOf('1')==-1)
						wherefilt += " category<>'UR' and";
					if(security.Substring(19,1).IndexOf('1')==-1)
						wherefilt += " category<>'UM' and";
					if(security.Substring(20,1).IndexOf('1')==-1)
						wherefilt += " category<>'UV' and";
				}
				//LAYOUT:
				if ( security.Substring(21,4).IndexOf('1')==-1) {
					wherefilt += " left(category,1)<>'L' and";	
				} else {
					if(security.Substring(21,1).IndexOf('1')==-1)
						wherefilt += " category<>'LH' and";
					if(security.Substring(22,1).IndexOf('1')==-1)
						wherefilt += " category<>'LB' and";
					if(security.Substring(23,1).IndexOf('1')==-1)
						wherefilt += " category<>'LM' and";
					if(security.Substring(24,1).IndexOf('1')==-1)
						wherefilt += " category<>'LV' and";
				}
				//PLUGINS:
				if(security.Substring(25,1).IndexOf('1')==-1)
					wherefilt += " category<>'PM' and";
				//LAYOUT:
				if ( security.Substring(26,3).IndexOf('1')==-1) {
					wherefilt += " left(category,1)<>'M' and";	
				} else {
					if(security.Substring(26,1).IndexOf('1')==-1)
						wherefilt += " category<>'MI' and";
					if(security.Substring(27,1).IndexOf('1')==-1)
						wherefilt += " category<>'MI' and";
					if(security.Substring(28,1).IndexOf('1')==-1)
						wherefilt += " category<>'MG' and";
				}
			return wherefilt;
		}
#endregion	
	}
}
